package qdu.testsocket3;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

public class TestSocketServer {
    static ServerSocket ss;//服务端三元组    
    static List<ClientHandler> clientList;//客户端线程对象的链表
    public static void main(String[] args) {
        clientList = new ArrayList<ClientHandler>();//初始化链表
        new TestSocketServer().initServer();//启动服务端监听               
    }
  
    static void showClientInfo() {//显示当前链表中的客户端信息        
        for(ClientHandler index : clientList){
            if(!index.clienSocket.isClosed())
                System.out.println("链接客户端IP:" + index.clienSocket.getInetAddress() + "客户端端口:" + index.clienSocket.getPort());
            else {
                clientList.remove(index);
            }
        }
        System.out.println("当前有" + clientList.size() + "个客户端链接:");
    }

    void initServer(){//启动服务端监听
        try {
            ss = new ServerSocket(9999);
            while(true){
                try {
                    Socket clinetSocket = ss.accept();//阻塞侦听客户端链接
                    if(clientList!= null){
                        ClientHandler ch = new ClientHandler(clinetSocket);//创建客户端链接对应的线程对象
                        ch.start();//启动客户端线程，在该线程中去接受当前客户端发来的消息
                        clientList.add(ch);//客户端线程对象放入链表
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
                showClientInfo();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    } 
}
class ClientHandler extends Thread{//每一个客户端对应一个线程对象
    public Socket clienSocket;//当前线程对应的socket对象
    public ClientHandler(Socket clienSocket){
        this.clienSocket = clienSocket;
    }
    public void run(){
        //只要网络链接正常，就不听的准备接受客户端的消息
        //每一个socket对象的流一般打开关闭一次
        BufferedReader br = null;
        try {
            br = new BufferedReader(
                new InputStreamReader(clienSocket.getInputStream())
            );
            while(clienSocket!= null && !clienSocket.isClosed()){
                //客户端的close函数正常关闭socket，在服务端体现为接受流返回null，或者isClosed函数返回true
                String message = br.readLine();//阻塞式
                //System.out.println("client msg received.....");
                if(message != null && !"".equals(message.trim())){
                    System.out.println("客户端:" + clienSocket.getInetAddress() + "发来消息：\n" + message);
                }
                else if(message == null)
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{//断开连接的收尾工作
            try {
                if(clienSocket != null){
                    clienSocket.close();
                    System.out.println("客户端:" + clienSocket.getInetAddress() + "断开连接");
                    clienSocket = null;
                }
                if(br!=null)
                    br.close();
                
                //更新链表
                TestSocketServer.clientList.remove(ClientHandler.this);
            } catch (Exception e) {}
        }    
    }
}